package com.yyoo.doc.mypdf.builder;

import com.lowagie.text.Element;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.yyoo.doc.html.style.StyleAttr;
import com.yyoo.doc.mypdf.MyPdfException;

import java.util.List;

/**
 * 表格标签
 *
 * @author zzy
 */
public class PdfTableBuilder extends PdfElementBuilder {

    /**
     * 获取表格宽度百分比
     */
    private float getWidthPercent(){
        float width = getWidth();
        return width > 100 ? 100 : width;
    }

    /**
     * 获取表格的列数
     * @return 列数
     */
    private int getTableCols(){
        int cols = Math.round(converToFloat(StyleAttr.COLS));

        if(cols == 0) {
            throw new MyPdfException("table 标签的 cols 属性（自定义属性）未设置，此属性用于设置表格的列数");
        }
        return cols;
    }

    /**
     * 获取表头行数
     * @return 表头行数
     */
    private int getHeaderRows(){
        return Math.round(converToFloat(StyleAttr.HEADER_ROWS));
    }

    /**
     * 获取表尾行数
     * @return 表尾行数
     */
    private int getFooterRows(){
        return Math.round(converToFloat(StyleAttr.FOOTER_ROWS));
    }

    /**
     * 根据表格的 列数，依次计算每列的宽度
     * 当 col-width 样式属性没有设值或设值不全时，自动按剩余百分比平均补全所有的列的宽度百分比
     * @param tableCols 表格的列数
     * @return 每列的宽度百分比数组
     */
    private int[] getTableColWidths(int tableCols){

        List<Integer> colWidths = converToListInteger(StyleAttr.COL_WIDTHS);

        int sum = colWidths.stream().reduce(0, Integer::sum);

        if(sum > 100){
            throw new MyPdfException("table 的列宽度百分比之和不能超过 100%");
        }

        int leaveNum = tableCols - colWidths.size();
        if(leaveNum > 0) {
            int leaveWidth = (100 - sum) / leaveNum;
            for (int i = colWidths.size(); i < tableCols; i++) {
                if (leaveWidth == 0) {
                    throw new MyPdfException("table 第 " + (i + 1) + " 列的宽度没有剩余百分比可分配了");
                }
                colWidths.add(leaveWidth);
            }
        }

        return colWidths.stream().mapToInt(Integer::intValue).toArray();
    }

    /**
     * 设置单元格固定高度
     * @param cell
     */
    private void setCellHeight(PdfPCell cell){
        Float cellHeight = converToFloat(StyleAttr.CELL_HEIGHT);
        if(cellHeight != null){
            cell.setFixedHeight(cellHeight);
        }
    }

    private void setMargin(PdfPTable table){
        Float marginTop = converToFloat(StyleAttr.MARGIN_TOP);
        if(marginTop != null){
            table.setSpacingBefore(marginTop);
        }
        Float marginBottom = converToFloat(StyleAttr.MARGIN_BOTTOM);
        if(marginBottom != null){
            table.setSpacingAfter(marginBottom);
        }
    }

    @Override
    public Element build() {
        int cols = getTableCols();
        PdfPTable table = new PdfPTable(cols);

        // 设置表格水平对齐方式
        table.setHorizontalAlignment(getTagAlign());
        // 设置表格宽度百分比
        table.setWidthPercentage(getWidthPercent());
        // 设置表头宽度百分比
        table.setWidths(getTableColWidths(cols));
        // 设置表格margin
        setMargin(table);

        // 设置边框宽度
        setBorderWidth(table.getDefaultCell());
        // 设置边框颜色
        setBorderColor(table.getDefaultCell());
        // 设置 padding
        setPadding(table.getDefaultCell());
        // 设置对齐方式
        table.getDefaultCell().setHorizontalAlignment(getHorizontalAlignment());
        table.getDefaultCell().setVerticalAlignment(getVerticalAlignment());
        setCellHeight(table.getDefaultCell());
        setBackgroundColor(table.getDefaultCell());
        // 设置位置
        setPostion(table.getDefaultCell());

        return table;
    }

    @Override
    public void afterBuild(Element el) {
        PdfPTable table = (PdfPTable) el;
        // 必须在表头添加之后设置才会有效
        table.setHeaderRows(getHeaderRows());
        table.setFooterRows(getFooterRows());
    }
}
